#ifndef _CONTAINER_PRINT_H_
#define _CONTAINER_PRINT_H_

#include "./stl_util_define.h"

namespace Container {

	using namespace std;
	using namespace Define;
	using namespace Text;

		/*!
			operator for adding POINTED objects in a container to a string into a new one
			\param str the first part of the resulting string
			\param set container to be inserted in the resulting string
			\return the string concatenation of both
			\sa template <class Tipo> inline string operator* ( const string &str, const vector<Tipo> &set );
			\code
			vector<int*> set;
			set, new int(1), new int(2), new int(3), new int(4);
			string list = "My_List: ";
			cout << list * set << endl; // prints "My_List: [ 1 2 3 4 ]"
			cout << list << endl; // prints "My_List:"
			\endcode
		*/
		template <class Tipo>
			inline string operator * ( const string &str, const vector<Tipo*> &set ) {
				string result = str * "[ ";
				for( usint i = 0; i < set.size(); ++i )
					(result *= (*set[i])) *= " ";
				return result *= "]";
			};

		/*!
			operator for adding objects in a container to a string into a new one
			\param str the first part of the resulting string
			\param set container to be inserted in the resulting string
			\return the string concatenation of both
			\sa template <class Tipo> inline string operator*= ( string &str, const vector<Tipo> &set );
			\code
			vector<int> set;
			set, 1, 2, 3, 4;
			string list = "My_List: ";
			cout << list * set << endl; // prints "My_List: [ 1 2 3 4 ]"
			cout << list << endl; // prints "My_List:"
			\endcode
		*/
		template <class Tipo>
			inline string operator * ( const string &str, const vector<Tipo> &set ) {
				string result = str * "[ ";
				for( usint i = 0; i < set.size(); ++i )
					(result *= (set[i])) *= " ";
				return result *= "]";
			};

		/*!
			operator for adding objects in a container into a string
			\param str the string to receive the printing
			\param set container to be printed
			\return the modified string
			\sa template <class Tipo> inline string operator* ( const string &str, const vector<Tipo> &set );
			\code
			vector<int> set;
			set, 1, 2, 3, 4;
			string list = "My_List: ";
			cout << (list *= set) << endl; // prints "My_List: [ 1 2 3 4 ]"
			cout << list << endl; // prints "My_List: [ 1 2 3 4 ]"
			\endcode
		*/
		template <class Tipo>
			inline string& operator *= ( string &str, const vector<Tipo> &set ) {
				return str = str * set;
			};

	/*!
		operator for printing objects which are inside a vector
		\param file the file to print
		\param set container to be printed
		\return the printed output stream
		\code
		vector<int> set;
		set, 1, 2, 3, 4;
		cout << set << endl; // prints [ 1 2 3 4 ]
		\endcode
	*/
	template <class Tipo>
		inline ostream& operator << ( ostream &file, const vector<Tipo> &set ) {
			using namespace StringAddition;
			return file << ( string("") * set );
		};

		/*!
			operator for adding POINTED objects in a container to a string into a new one
			\param str the first part of the resulting string
			\param set container to be inserted in the resulting string
			\return the string concatenation of both
			\sa template <class Tipo> inline string operator* ( const string &str, const deque<Tipo> &set );
			\code
			deque<int*> set;
			set, new int(1), new int(2), new int(3), new int(4);
			string list = "My_List: ";
			cout << list * set << endl; // prints "My_List: [ 1 2 3 4 ]"
			cout << list << endl; // prints "[ 1 2 3 4 ]"
			\endcode
		*/
		template <class Tipo>
			inline string operator * ( const string &str, const deque<Tipo*> &set ) {
				string result = str * "[ ";
				for( usint i = 0; i < set.size(); ++i )
					(result *= (*set[i])) *= " ";
				return result *= "]";
			};

		/*!
			operator for adding objects in a container to a string into a new one
			\param str the first part of the resulting string
			\param set container to be inserted in the resulting string
			\return the string concatenation of both
			\sa template <class Tipo> inline string operator*= ( string &str, const deque<Tipo> &set );
			\code
			deque<int> set;
			set, 1, 2, 3, 4;
			string list = "My_List: ";
			cout << list * set << endl; // prints "My_List: [ 1 2 3 4 ]"
			cout << list << endl; // prints "[ 1 2 3 4 ]"
			\endcode
		*/
		template <class Tipo>
			inline string operator * ( const string &str, const deque<Tipo> &set ) {
				string result = str * "[ ";
				for( usint i = 0; i < set.size(); ++i )
					(result *= (set[i])) *= " ";
				return result *= "]";
			};

		/*!
			operator for adding objects in a container into a string
			\param str the string to receive the printing
			\param set container to be printed
			\return the modified string
			\sa template <class Tipo> inline string operator* ( const string &str, const deque<Tipo> &set );
			\code
			deque<int> set;
			set, 1, 2, 3, 4;
			string list = "My_List: ";
			cout << (list *= set) << endl; // prints "My_List: [ 1 2 3 4 ]"
			cout << list << endl; // prints "My_List: [ 1 2 3 4 ]"
			\endcode
		*/
		template <class Tipo>
			inline string& operator *= ( string &str, const deque<Tipo> &set ) {
				return str = str * set;
			};

	/*!
		operator for printing objects which are inside a deque
		\param file the file to print
		\param set container to be printed
		\return the printed output stream
		\code
		deque<int> set;
		set, 1, 2, 3, 4;
		cout << set << endl; // prints [ 1 2 3 4 ]
		\endcode
	*/
	template <class Tipo>
		inline ostream& operator << ( ostream &file, const deque<Tipo> &set ) {
			using namespace StringAddition;
			return file << ( string("") * set );
		};
};

#endif // _CONTAINER_PRINT_H_
